package cs348a.test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.io.File;
import java.util.ArrayList;

import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileNameExtensionFilter;

import cs348a.color.PaletteModel;
import cs348a.data.EdgeFileData;
import cs348a.data.SequenceData;
import cs348a.data.Site;
import cs348a.io.OptimizerCommander;
import cs348a.io.SequenceWriter;
import cs348a.opengl.JoglPanel;
import cs348a.opengl.JoglPerspective;
import cs348a.opengl.object.OpenGLSequencePath;
import cs348a.opengl.object.OpenGLSite;
import cs348a.opengl.object.OpenGLSurface;
import cs348a.test.pilot.*;

public class NavigationFrame extends JFrame {
	/** saves the current sequence here */
	private String currentSeqFile = "..//data//finalData//current.sequence";
	
	// Layout constants
	public static int TOOLBAR_WIDTH = 140;
	private Dimension btDim = new Dimension(TOOLBAR_WIDTH-15, 25);
	private Dimension panelDim = new Dimension(500, 500);
	
	// UI scales
	private double scale = 1;
	private double scaleZ = 10;
	private int zOffset = 50;
	
	// File filters
	private JFileChooser fileChooser;
	private FileNameExtensionFilter edgeFilter = new FileNameExtensionFilter(null, "edges");
	private FileNameExtensionFilter sequenceFilter = new FileNameExtensionFilter(null, "sequence");
	
	/** The pilot panel */
	private JoglPanel pilotPanel;
	
	/** The observer panel */
	private JoglPanel obvPanel;

	private PaletteModel paletteModel = new PaletteModel();
	
	// OpenGLObjects
	private OpenGLSurface surface = null;
	private ArrayList<OpenGLSite> seqList = new ArrayList<OpenGLSite>();
	private boolean showPoints = false;
	private OpenGLSequencePath seqPath = null;
	private Site pilotSite = null;
	private OpenGLSite pilotGLSite = null;
	
	private GLUquadric theQuad = new GLU().gluNewQuadric(); 
	
	// Data structures
	private EdgeFileData efData = new EdgeFileData();
	private SequenceData seqData = new SequenceData();
	
	// The pilot(navigator)
	private Pilot pilot;

	/** Optimizer commander */
	private OptimizerCommander oc = new OptimizerCommander();
	
	// Position ui
	private JFormattedTextField xPosTF;
	private JFormattedTextField yPosTF;
	private JFormattedTextField zPosTF;
	
	/**
	 * Constructor
	 */
	public NavigationFrame() {
		setTitle("CS348A Project");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setPreferredSize(new Dimension(1200, 600));
		
		initComponents();
		
		build();
	}
	
	/**
	 * Initializes the components
	 */
	private void initComponents() {
		// Initialize file chooser
		fileChooser = new JFileChooser();
		fileChooser.setCurrentDirectory(new File("..//data//finalData"));
		fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
		fileChooser.setMultiSelectionEnabled(false);
		
		// Initialize pilot panel
		pilotPanel = new JoglPanel();
		pilotPanel.setPreferredSize(panelDim);
		pilotPanel.startAnimation();
		pilotPanel.addMouseAdapter(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				super.mouseClicked(e);
				
				if(e.getClickCount() > 1) {
					pilot.setZOffset(Pilot.DEFAULT_Z);
				}
			}
			
			@Override
			public void mouseWheelMoved(MouseWheelEvent e) {
				super.mouseWheelMoved(e);
				
				int rot = e.getWheelRotation();

				JoglPerspective perspective = pilotPanel.perspective();
				
				if(pilot.isRunning()) {
					if(e.isControlDown() || e.isAltDown()){ // change view angle
						if(rot > 0){ // scroll up
							if(perspective.angle+5 < JoglPerspective.MAX_ANGLE)
								perspective.angle += 5;
						} else { // scroll down
							if(perspective.angle-5 > JoglPerspective.MIN_ANGLE)
								perspective.angle -= 5;
						}
					} else { // change view height
						if(rot > 0){ // scroll up
							pilot.setZOffset(pilot.getZOffset() - zOffset);
						} else { // scroll down
							pilot.setZOffset(pilot.getZOffset() + zOffset);
						}
					}
				}
			}
		});
		
		pilot = new PointPilot(pilotPanel.perspective());
		pilot.setPilotListener(new PilotListener() {
			
			@Override
			public void pilotChanged(float[] p) {
				pilotSite.x = p[0];
				pilotSite.y = p[1];
				pilotSite.z = p[2];
				
				updatePosPanel(p);
			}
		});

		// Initialize observer panel
		obvPanel = new JoglPanel();
		obvPanel.setPreferredSize(panelDim);
		obvPanel.startAnimation();
		obvPanel.addMouseAdapter(new MouseAdapter(){
			private double prevX = 0;
			private double prevY = 0;
			
			@Override
			public void mouseClicked(MouseEvent e) {
				super.mouseClicked(e);
				
				if(e.getClickCount() > 1) {
					initializeObserverView();
				}
			}
			
			@Override
			public void mouseWheelMoved(MouseWheelEvent e) {
				super.mouseWheelMoved(e);
				
				int rot = e.getWheelRotation();

				JoglPerspective perspective = obvPanel.perspective();

				if(e.isControlDown() || e.isAltDown()){ // change view angle
					if(rot > 0){ // scroll up
						if(perspective.angle+5 < JoglPerspective.MAX_ANGLE)
							perspective.angle += 5;
					} else { // scroll down
						if(perspective.angle-5 > JoglPerspective.MIN_ANGLE)
							perspective.angle -= 5;
					}
				} else { // change view height
					if(rot > 0){ // scroll up
						perspective.viewPosition[2] += scaleZ;
					} else { // scroll down
						perspective.viewPosition[2] -= scaleZ;
					}
				}
			}
			
			@Override
			public void mouseDragged(MouseEvent e) {
				super.mouseDragged(e);
				
				float dx = (float) (e.getX() - prevX);
				float dy = (float) (e.getY() - prevY);
				
				prevX = e.getX();
				prevY = e.getY();
				
				JoglPerspective perspective = obvPanel.perspective();
				
				// this is panning
				perspective.viewPosition[0] -= dx*scale;
				perspective.viewPosition[1] += dy*scale;
				perspective.objectPosition[0] -= dx*scale;
				perspective.objectPosition[1] += dy*scale;
			}
			
			@Override
			public void mouseMoved(MouseEvent e) {
				super.mouseMoved(e);
				
				prevX = e.getX();
				prevY = e.getY();
			}
		});
	
	}

	/**
	 * Builds the frame
	 */
	private void build() {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		setJMenuBar(createMenuBar());
		setLayout(new BorderLayout());
				
		add(pilotPanel, BorderLayout.EAST);
		add(createControlPanel(), BorderLayout.CENTER);
		add(obvPanel, BorderLayout.WEST);
	}
	
	/**
	 * Creates the control panel
	 * 
	 * @return
	 */
	private Component createControlPanel() {
		JPanel panel = new JPanel();
		panel.setPreferredSize(new Dimension(TOOLBAR_WIDTH, 600));

		panel.setLayout(new FlowLayout());
		
		panel.add(createViewPanel());
		panel.add(createPilotPanel());
		panel.add(createModifyPanel());
		panel.add(createPosPanel());
//		panel.add(createDebugPanel());
		
		return panel;
	}
	
	private Component createPosPanel() {
		xPosTF = new JFormattedTextField();
		xPosTF.setSize(new Dimension(50, 20));
		xPosTF.setEditable(false);
		xPosTF.setValue(0);
		
		yPosTF = new JFormattedTextField();
		yPosTF.setSize(new Dimension(50, 20));
		yPosTF.setEditable(false);
		yPosTF.setValue(0);
		
		zPosTF = new JFormattedTextField();
		zPosTF.setSize(new Dimension(50, 20));
		zPosTF.setEditable(false);
		zPosTF.setValue(0);
		
		JPanel panel = new JPanel();
		panel.setPreferredSize(new Dimension(TOOLBAR_WIDTH-10, 75));
		panel.setLayout(new GridLayout(0, 2));
		panel.add(new JLabel("X: "));
		panel.add(xPosTF);
		panel.add(new JLabel("Y: "));
		panel.add(yPosTF);
		panel.add(new JLabel("Z: "));
		panel.add(zPosTF);
		
		return panel;
	}

//	private Component createDebugPanel() {
//		JButton goBT = new JButton("Go");
//		goBT.setPreferredSize(btDim);
//		goBT.addActionListener(new ActionListener() {
//			
//			@Override
//			public void actionPerformed(ActionEvent e) {
//				pilot.setPosition(68/2, 5);
//			}
//		});
//		
//		JPanel panel = new JPanel();
//		panel.setPreferredSize(new Dimension(TOOLBAR_WIDTH-10, 50));
//		panel.setLayout(new FlowLayout());
//
//		panel.add(goBT);
//		
//		return panel;
//	}

	/**
	 * Creates the on-the-fly modification panel
	 * 
	 * @return
	 */
	private Component createModifyPanel() {
		final float[] p = new float[3];
		
//		final NumberFormat format = NumberFormat.getIntegerInstance();
		
		final JFormattedTextField xTF = new JFormattedTextField();
		xTF.setSize(new Dimension(50, 20));
		xTF.setValue(0);
		
		final JFormattedTextField yTF = new JFormattedTextField();
		yTF.setSize(new Dimension(50, 20));
		yTF.setValue(0);
		
		final JFormattedTextField zTF = new JFormattedTextField();
		zTF.setSize(new Dimension(50, 20));
		zTF.setValue(0);
		
		JPanel xyzPanel = new JPanel();
		xyzPanel.setPreferredSize(new Dimension(TOOLBAR_WIDTH-15, 75));
		xyzPanel.setLayout(new GridLayout(0, 2));
		xyzPanel.add(new JLabel("X: "));
		xyzPanel.add(xTF);
		xyzPanel.add(new JLabel("Y: "));
		xyzPanel.add(yTF);
		xyzPanel.add(new JLabel("Z: "));
		xyzPanel.add(zTF);
		
		JButton addBT = new JButton("Add Next");
		addBT.setPreferredSize(btDim);
		addBT.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				p[0] = ((Number)xTF.getValue()).floatValue();
				p[1] = ((Number)yTF.getValue()).floatValue();
				p[2] = ((Number)zTF.getValue()).floatValue();
				
				System.out.println("X/Y/Z: "
						+ p[0] + "/" + p[1] + "/" + p[2]);
				
				addNextSite(p);
			}
			
		});
		
		JButton deleteBT = new JButton("Delete Next");
		deleteBT.setPreferredSize(btDim);
		deleteBT.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				deleteNextSite();
			}
			
		});

		JPanel panel = new JPanel();
		panel.setPreferredSize(new Dimension(TOOLBAR_WIDTH-10, 150));
		panel.setBorder(LineBorder.createGrayLineBorder());
		panel.setLayout(new FlowLayout());

		panel.add(xyzPanel);
		panel.add(addBT);
		panel.add(deleteBT);
		
		return panel;
	}

	/**
	 * Creates the pilot panel
	 * 
	 * @return
	 */
	private Component createPilotPanel() {
		JButton startBT = new JButton("Start");
		startBT.setPreferredSize(btDim);
		startBT.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				pilot.startTour();
			}
			
		});
		
		JButton stopBT = new JButton("Stop");
		stopBT.setPreferredSize(btDim);
		stopBT.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				pilot.stopTour();
			}
			
		});
		
		// Speed slider
		final JSlider speedSL = new JSlider(JSlider.HORIZONTAL, 0, 2, 1);
		speedSL.setPreferredSize(new Dimension(TOOLBAR_WIDTH-20, 25));
		speedSL.addChangeListener(new ChangeListener(){

			@Override
			public void stateChanged(ChangeEvent e) {
				int ti = 100;
				
				if(speedSL.getValue() == 0) {
					ti = 1000;
				} else if (speedSL.getValue() == 2) {
					ti = 10;
				} else {
					ti = 100;
				}
				
				pilot.setTimeInterval(ti);
			}
			
		});
		
		JButton modeBT = new JButton("Pilot Mode");
		modeBT.setPreferredSize(btDim);
		modeBT.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				pilot.setMode(!pilot.isLookingDown());
			}
			
		});
		
		JPanel panel = new JPanel();
		panel.setPreferredSize(new Dimension(TOOLBAR_WIDTH-10, 150));
		panel.setBorder(LineBorder.createGrayLineBorder());
		panel.setLayout(new FlowLayout());
		
		panel.add(startBT);
		panel.add(stopBT);
		panel.add(new JLabel("Speed"));
		panel.add(speedSL);
		panel.add(modeBT);
		
		return panel;
	}

	/**
	 * Creates a view control panel
	 * 
	 * @return
	 */
	private Component createViewPanel() {
		// Show points button
		final JToggleButton pointBT = new JToggleButton("Show Ctrl Pts", showPoints);
		pointBT.setPreferredSize(btDim);
		pointBT.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				showPoints = pointBT.isSelected();
				showControlPoints(showPoints);
			}
			
		});
		
		// Reset View button
		final JButton resetBT = new JButton("Reset Pilot View");
		resetBT.setPreferredSize(btDim);
		resetBT.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {		
				initializePilotView();
			}
			
		});
		
		// Opacity slider
		final JSlider opacitySL = new JSlider(JSlider.HORIZONTAL, 0, 100, 80);
		opacitySL.setPreferredSize(new Dimension(TOOLBAR_WIDTH-20, 25));
		opacitySL.addChangeListener(new ChangeListener(){

			@Override
			public void stateChanged(ChangeEvent e) {
				 if(surface != null) {
			    	 surface.opacity(opacitySL.getValue()/100f);
			     }
			}
			
		});

		JPanel panel = new JPanel();
		panel.setPreferredSize(new Dimension(TOOLBAR_WIDTH-10, 125));
		panel.setBorder(LineBorder.createGrayLineBorder());
		panel.setLayout(new FlowLayout());
		
		panel.add(pointBT);
		panel.add(resetBT);
		panel.add(new JLabel("Surface Opacity"));
		panel.add(opacitySL);
		return panel;
	}

	/**
	 * Creates the menu bar.
	 * 
	 * @return
	 */
	private JMenuBar createMenuBar() {
		JMenuBar menuBar = new JMenuBar();
		
		JMenu fileMenu = new JMenu("File");
		
		JMenuItem ltItem = new JMenuItem("Load Terrain");
		ltItem.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				openTerrainFile();
			}
			
		});
		fileMenu.add(ltItem);
		
//		JMenuItem lpItem = new JMenuItem("Load Tour");
//		lpItem.addActionListener(new ActionListener() {
//
//			@Override
//			public void actionPerformed(ActionEvent e) {
//				openPathFile();
//			}
//			
//		});
//		fileMenu.add(lpItem);
		
		JMenuItem lsItem = new JMenuItem("Load Sequence");
		lsItem.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				openSequenceFile();
			}
			
		});
		fileMenu.add(lsItem);
		
		fileMenu.addSeparator();
		
		JMenuItem exitItem = new JMenuItem("Exit");
		exitItem.addActionListener(new ActionListener() {
		
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(EXIT_ON_CLOSE);
			}
		});
		fileMenu.add(exitItem);
		
		menuBar.add(fileMenu);
		
		return menuBar;
	}
	
	/**
	 * Adds the next site
	 */
	private void addNextSite(float[] p) {
		oc.addNextPoint(pilot, seqData, p);

		Object[] options = {"Done", "Cancel"};

		int n = JOptionPane.showOptionDialog(
				this
				, "Wait for optimizer"
				, "Wait"
				, JOptionPane.YES_NO_OPTION
				, JOptionPane.QUESTION_MESSAGE
				, null
				, options
				, options[0]);
		
		if(n == 0) {
			oc.handleAddData();	
			
			removeSeqPoints();
			addSeqPoints();
			
			SequenceWriter.writeSiteFile(seqData.siteList, currentSeqFile);
		}
	}
	
	/**
	 * Deletes the next site
	 */
	private void deleteNextSite() {
		oc.deleteNextPoint(pilot, seqData);

		Object[] options = {"Done", "Cancel"};

		int n = JOptionPane.showOptionDialog(
				this
				, "Wait for optimizer"
				, "Wait"
				, JOptionPane.YES_NO_OPTION
				, JOptionPane.QUESTION_MESSAGE
				, null
				, options
				, options[0]);
		
		if(n == 0) {
			oc.handleDeleteData();
			
			removeSeqPoints();
			addSeqPoints();
			
			SequenceWriter.writeSiteFile(seqData.siteList, currentSeqFile);
		}
	}

	/**
	 * Opens terrain file
	 */
	private void openTerrainFile() {
		fileChooser.setFileFilter(edgeFilter);
		
		if(fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();
			
			efData.parseDataFile(file);
			efData.triangulate();
			
			// initalize view
			initializePilotView();
			initializeObserverView();
			updateUIScales();
			
			// Remove GL Objects
			pilotPanel.removeAllGLObjects();
			obvPanel.removeAllGLObjects();
			
			// create surface
			createSurfaceObject();
		}
	}
	
	/**
	 * Updates the UI scales
	 */
	private void updateUIScales() {
		// get UI scale factors
		double rangeX = efData.maxX-efData.minX;
		double rangeY = efData.maxY-efData.minY;
		scale = Math.min(rangeX, rangeY)/640;
		
		double rangeZ = efData.maxZ-efData.minZ;
		scaleZ = 100*(rangeZ/255)*(rangeZ/255);
	}

//	/**
//	 * Opens terrain file
//	 */
//	private void openPathFile() {
//		fileChooser.setFileFilter(tourFilter);
//		
//		if(fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
//			File file = fileChooser.getSelectedFile();
//
//			tourData.parseDataFile(file);
//			
//			createTourObject();
//		}
//	}
	
	/**
	 * Opens the sequence file
	 */
	private void openSequenceFile() {
		fileChooser.setFileFilter(sequenceFilter);
		
		if(fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();

			seqData.parseDataFile(file);
			
			createSequenceObject();
			pilot.setSequenceData(seqData);
			
			// Add pilot point
			Site s = seqData.siteList.get(0);
			pilotSite = new Site(s.x, s.y, s.z, -1);
			pilotGLSite = new OpenGLSite(pilotSite, theQuad);
			pilotGLSite.radius(150);
			pilotGLSite.onColor(Color.GREEN);
			obvPanel.addGLObject(pilotGLSite);
			
			SequenceWriter.writeSiteFile(seqData.siteList, currentSeqFile);
		}
	}

	/**
	 * Initializes the perspective
	 */
	private void initializePilotView() {
		JoglPerspective perspective = pilotPanel.perspective();
		perspective.setEnabled(true);
		perspective.angle = JoglPerspective.DEFAULT_ANGLE;
		
		perspective.viewPosition[0] = (efData.minX+efData.maxX)/2;
		perspective.viewPosition[1] = (efData.minY+efData.maxY)/2;
		perspective.viewPosition[2] = 5f*efData.maxZ;
		
		perspective.objectPosition[0] = (efData.minX+efData.maxX)/2;
		perspective.objectPosition[1] = (efData.minY+efData.maxY)/2;
		perspective.objectPosition[2] = 0;
		
		perspective.upDirection = new float[] {0, 1, 0};
		
		perspective.orthoWidth = (efData.maxX-efData.minX);
		perspective.orthoHeight = (efData.maxY-efData.minY);
		
		perspective.far = 10*efData.maxZ;
	}

	/**
	 * Initializes the perspective
	 */
	private void initializeObserverView() {
		JoglPerspective perspective = obvPanel.perspective();
		perspective.setEnabled(true);
		perspective.angle = 45;
		
		perspective.viewPosition[0] = (efData.minX+efData.maxX)/2;
		perspective.viewPosition[1] = efData.minY;
		perspective.viewPosition[2] = efData.maxX-efData.minX;
		
		perspective.objectPosition[0] = (efData.minX+efData.maxX)/2;
		perspective.objectPosition[1] = (efData.minY+efData.maxY)/2;
		perspective.objectPosition[2] = 0;
		
		perspective.upDirection = new float[] {0, 0, 1};
		
		perspective.orthoWidth = (efData.maxX-efData.minX);
		perspective.orthoHeight = (efData.maxY-efData.minY);
		
		perspective.far = 100*efData.maxZ;
	}

	/**
	 * Creates a surface object.
	 */
	private void createSurfaceObject() {
		surface = new OpenGLSurface(efData);
		surface.paletteModel(paletteModel);
		
		pilotPanel.addGLObject(surface);
		obvPanel.addGLObject(surface);
	}

//	/**
//	 * Creates a tour object
//	 */
//	private void createTourObject() {
//		for(Site s : tourData.siteList) {
//			OpenGLSite os = new OpenGLSite(s, theQuad);
//			os.radius(200);
//			os.onColor(Color.RED);
//			
//			pilotPanel.addGLObject(os);
//			obvPanel.addGLObject(os);
//		}
//	}

	/**
	 * Updates the position panel.
	 */
	private void updatePosPanel(float[] p) {
		xPosTF.setValue(p[0]);
		yPosTF.setValue(p[1]);
		zPosTF.setValue(p[2]);
		
		xPosTF.updateUI();
		yPosTF.updateUI();
		zPosTF.updateUI();
	}
	
	/**
	 * Shows control points
	 */
	public void showControlPoints(boolean show) {
		for(OpenGLSite os : seqList) {
			if(!os.isTourSite()){
				os.setVisible(show);
			}
		}
	}
	
	/**
	 * Creates a tour object
	 */
	private void createSequenceObject() {
		if(seqPath != null) {
			removeSeqPoints();
			pilotPanel.removeGLObject(seqPath);
			obvPanel.removeGLObject(seqPath);
			obvPanel.removeGLObject(pilotGLSite);
		}
		
		seqPath = new OpenGLSequencePath(seqData);
		pilotPanel.addGLObject(seqPath);
		obvPanel.addGLObject(seqPath);
		
		addSeqPoints();
	}

	/**
	 * Adds the points
	 */
	private void addSeqPoints() {
		
		for(Site s : seqData.siteList) {
			OpenGLSite os = new OpenGLSite(s, theQuad);
			os.radius(100);
			os.onColor(Color.white);
			
			seqList.add(os);
			pilotPanel.addGLObject(os);
			obvPanel.addGLObject(os);
		}
		
		showControlPoints(showPoints);
	}
	
	/**
	 * Removes all sequence data
	 */
	private void removeSeqPoints() {
		for(OpenGLSite os : seqList) {
			pilotPanel.removeGLObject(os);
			obvPanel.removeGLObject(os);
		}
		
		seqList.clear();
	}

	/**
	 * The main routine
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		JFrame frame = new NavigationFrame();
		
		frame.pack();
		frame.setVisible(true);
	}
}
